from flask import render_template, redirect, url_for, abort, flash, request, \
    current_app
from flask_login import login_required, current_user
from . import main
from .forms import EditProfileForm, PostForm, SearchForm, UploadForm, photos
from .. import db
from ..models import User, Post
from sqlalchemy import extract
import os
import time
import hashlib
from flask_uploads import UploadSet, configure_uploads, IMAGES, patch_request_class
from flask import current_app


@main.route('/', methods=['GET', 'POST'])
def index():
    form = PostForm()
    search = SearchForm()
    if not search.validate_on_submit():
        if current_user.can() and form.validate_on_submit():
            post = Post(body=form.body.data,
                        author=current_user._get_current_object())
            db.session.add(post)
            db.session.commit()
            return redirect(url_for('.index'))
    if not form.validate_on_submit():
        if current_user.can() and search.validate_on_submit():
            time = search.dateSearch.data
            page = request.args.get('page', 1, type=int)
            date_pagination = Post.query.filter(Post.author_id == current_user.id).filter(
                extract('year', Post.timestamp) == time.year,
                extract('month', Post.timestamp) == time.month,
                extract('day', Post.timestamp) == time.day).paginate(
                page, per_page=10,
                error_out=False)
            date_posts = date_pagination.items
            form = PostForm()
            return render_template('index.html', form=form, search=search, posts=date_posts,
                                   pagination=date_pagination)
    page = request.args.get('page', 1, type=int)
    if current_user.can():
        pagination = Post.query.filter(Post.author_id == current_user.id).order_by(Post.timestamp.desc()).paginate(
            page, per_page=10,
            error_out=False)
    else:
        pagination = Post.query.order_by(Post.timestamp.desc()).paginate(
            page, per_page=10,
            error_out=False)
    posts = pagination.items
    return render_template('index.html', form=form, posts=posts, search=search,
                           pagination=pagination)


@main.route('/user/<username>')
def user(username):
    user = User.query.filter_by(username=username).first_or_404()
    page = request.args.get('page', 1, type=int)
    pagination = user.posts.order_by(Post.timestamp.desc()).paginate(
        page, per_page=10,
        error_out=False)
    posts = pagination.items
    return render_template('user.html', user=user, posts=posts,
                           pagination=pagination)


@main.route('/edit-profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
    form = EditProfileForm()
    if form.validate_on_submit():
        current_user.name = form.name.data
        current_user.location = form.location.data
        current_user.about_me = form.about_me.data
        db.session.add(current_user._get_current_object())
        db.session.commit()
        flash('Your profile has been updated.')
        return redirect(url_for('.user', username=current_user.username))
    form.name.data = current_user.name
    form.location.data = current_user.location
    form.about_me.data = current_user.about_me
    return render_template('edit_profile.html', form=form)


@main.route('/post/<int:id>')
def post(id):
    post = Post.query.get_or_404(id)
    return render_template('post.html', posts=[post])


@main.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
def edit(id):
    post = Post.query.get_or_404(id)
    if current_user != post.author and \
            not current_user.can():
        abort(403)
    form = PostForm()
    if form.validate_on_submit():
        post.body = form.body.data
        db.session.add(post)
        db.session.commit()
        flash('The post has been updated.')
        return redirect(url_for('.post', id=post.id))
    form.body.data = post.body
    return render_template('edit_post.html', form=form)


@main.route('/delete/<int:id>', methods=['GET', 'POST'])
@login_required
def delete(id):
    post = Post.query.get_or_404(id)
    db.session.delete(post)
    db.session.commit()
    flash('The post has been deleted.')
    return redirect(url_for('.index'))


# -------------------------------------------------------------------
# drive

@main.route('/photo_drive/<username>', methods=['GET', 'POST'])
@login_required
def photo_drive(username):
    form = UploadForm()
    if form.validate_on_submit():
        for filename in request.files.getlist('photo'):
            str_name = username + str(int(time.time()))
            name = "[" + username + "]" + hashlib.md5(str_name.encode("utf-8")).hexdigest()[:15]
            photos.save(filename, name=name + '.')
        success = True
    else:
        success = False
    if success:
        flash('Added your photo to MyLog drive successfully! Press manage to check it!')
    return render_template('drive.html', form=form)


@main.route('/manage_photo/<username>')
@login_required
def manage_photo(username):
    app = current_app._get_current_object()
    files_list = os.listdir(app.config['UPLOADED_PHOTOS_DEST'])
    selected_files_list = [item for item in files_list if item.startswith("[" + username + "]")]
    return render_template('manage.html', files_list=selected_files_list)


@main.route('/open_photo/<username>/<filename>')
@login_required
def open_photo(filename, username):
    file_url = photos.url(filename)
    return render_template('browser.html', file_url=file_url)


@main.route('/delete_photo/<username>/<filename>')
@login_required
def delete_photo(filename, username):
    file_path = photos.path(filename)
    os.remove(file_path)
    return redirect(url_for('.manage_photo', username=username))
